﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using SmartMusicBox.ViewModel;
using SmartMusicBox.Framework.Helper;
using System.Diagnostics;
using GalaSoft.MvvmLight.Messaging;

namespace SmartMusicBox.Framework.Navigation
{
    public class NavigationService
    {
        private object _userData = null;
        private bool _registeredFailedNavigation = false;

        public void StartService()
        {
            Messenger.Default.Register<NavigateMessage>(this,false, OnNavigateTo);
        }

        public void StopService()
        {
            Messenger.Default.Unregister<NavigateMessage>(this, OnNavigateTo);
        }

        bool _initialized = false;
        private void InitializeNavigatedRegistration()
        {
            if (_initialized)
                return;
            _initialized = true;

            Frame.Navigated += (s, e) => {
                var page = Frame.Content as PhoneApplicationPage;
                if (page != null)
                {
                    var vm = page.DataContext as SmartViewModelBase;
                    vm.NavigateTo(_userData);
                }
                _userData = null;
            };
        }

        private void OnNavigateTo(NavigateMessage obj)
        {
            if (obj.Data != null)
            {
                InitializeNavigatedRegistration();
                _userData = obj.Data;
            }

            if (!_registeredFailedNavigation)
            {
                _registeredFailedNavigation = true;
                Frame.NavigationFailed += new NavigationFailedEventHandler(Frame_NavigationFailed);
            }

            DispatcherHelper.BeginInvokeOnUIThread(() => DoActualNavigation(obj));
        }

        private void DoActualNavigation(NavigateMessage obj)
        {
            try
            {
                Frame.Navigate(new Uri(GetPageUriString(obj), UriKind.Relative));
            }
            catch (Exception ex)
            {
                FrameNavigationFailed(ex, GetPageUriString(obj));
            }
        }

        private string GetPageUriString(NavigateMessage obj)
        {
            return string.Concat("/View/", obj.PageName, ".xaml");
        }

        private void FrameNavigationFailed(Exception ex, string Uri)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                Debug.WriteLine("Failed:" + Uri);
                System.Diagnostics.Debugger.Break();
            }
        }

        void Frame_NavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            e.Handled = true;
            FrameNavigationFailed(e.Exception, e.Uri.OriginalString);
        }

        private PhoneApplicationFrame _frame;
        public PhoneApplicationFrame Frame
        {
            get
            {
                if (_frame == null)
                {
                    _frame = (PhoneApplicationFrame)(Application.Current.RootVisual);
                }
                return _frame;
            }
            set
            {
                _frame = value;
            }
        }
    }
}
